import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 35326
 * 2021/3/25 16:14
 * 动态代理的测试和使用
 *
 * 要想实现动态代理，需要解决的问题？
 * 1. 如何根据加载到内存中的被代理类，动态的创建一个代理类的对象
 * 2. 当通过代理类的方法时 ，如何调用被代理类的方法
 */
public class ProxyTest {
	public static void main(String[] args) {
		//此时这就是代理类的对象
		Human proxyInstance = (Human)getProxyInstance(new SuperMan());
		proxyInstance.eat("四川麻辣烫");
		System.out.println(proxyInstance.getBelieve());
	}
	/**
	 *
	 * @param obj 被代理类的对象
	 * @return
	 */
	public static Object getProxyInstance(Object obj){
		Object o = Proxy.newProxyInstance(obj.getClass().getClassLoader(),
				obj.getClass().getInterfaces(),
				new InvocationHandler() {

//					private Object obj;//被代理类对象
					/**
					 * 当通过代理类的对象调用方法a时，就会动态的调用如下的invoke()方法
					 * @param proxy
					 * @param method
					 * @param args
					 * @return
					 * @throws Throwable
					 */
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						Object invoke = method.invoke(obj, args);
						return invoke;
					}
				});
		return o;
	}
}

interface Human{
	String getBelieve();
	void eat(String food);
}

class SuperMan implements Human{
	@Override
	public String getBelieve() {
		return "I believe I can fly!";
	}

	@Override
	public void eat(String food) {
		System.out.println("超人吃什么食物？");
	}
}
